/*
 * Group 3, User Interface Programming II (vt11)
 * Pooya | Flora | Monica | Can
 */
package vical.view;

import java.awt.*;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import vical.controller.PreferenceController;
import vical.model.WeekModel;
import vical.view.model.TimeLineModel;

/**
 * The week view for this calendar application.
 *
 * @author Can
 */
public class WeekView extends AbstractView {

    private WeekModel model;
    private int timeLineWidth;
    // components
    private JScrollPane scrollPanel;
    private JPanel centerPanel;
    private JPanel columnsPanel;
    private JPanel topPanel;
    private TimeLineRuler timeLine;
    private ViewPanel viewPanel;
    private Component rightCorner;

    public WeekView(ViewPanel viewPanel, WeekModel weekModel) {
        this.viewPanel = viewPanel;
        this.model = weekModel;
        this.timeLineWidth = 50;
        initComponents();
    }

    private void initComponents() {
        TimeLineModel timeLineModel = new TimeLineModel();
        // center part
        centerPanel = new JPanel(new GridLayout(1, model.getDayNumbers(), 0, 0));
        for (int i = 0; i < model.getDayNumbers(); i++) {
            DayBoardContent day = new DayBoardContent(model.getDayModel(i), timeLineModel);
            day.setPreferredSize(new Dimension(10, timeLineModel.getTotalLength()));
            day.setBorder(BorderFactory.createLineBorder(Color.GRAY));
            centerPanel.add(day);
        }
        scrollPanel = new JScrollPane(centerPanel,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPanel.setAutoscrolls(true);
        scrollPanel.getViewport().addChangeListener(new ChangeListener() {

            public void stateChanged(ChangeEvent e) {
                Object o = e.getSource();
                if (o instanceof JViewport) {
                    if (topPanel != null) {
                        int widthCenter = ((JViewport) o).getWidth();
                        int widthTopPanel = topPanel.getWidth();
                        int widthRightCorner = widthTopPanel - widthCenter - timeLineWidth - 2;
                        if (rightCorner != null) {
                            topPanel.remove(rightCorner);
                        }
                        rightCorner = Box.createRigidArea(new Dimension(widthRightCorner, 0));
                        topPanel.add(BorderLayout.EAST, rightCorner);
                        topPanel.revalidate();
                    }
                }
            }
        });
        scrollPanel.getViewport().setViewPosition(new Point(0, 150));
        scrollPanel.setWheelScrollingEnabled(true);

        // timeline / rows
        timeLine = new TimeLineRuler(timeLineModel);
        timeLine.setPreferredSize(new Dimension(timeLineWidth, timeLineModel.getTotalLength()));
        scrollPanel.setRowHeaderView(timeLine);

        // columns
        columnsPanel = new JPanel();
        columnsPanel.setLayout(new GridLayout(1, model.getDayNumbers(), 0, 0));
        Calendar day = model.getFirstDay();
        for (int i = 0; i < model.getDayNumbers(); i++) {
            columnsPanel.add(new DayBoardHeader(this, model.getAllDayEntries(day), day));
            day.add(Calendar.DATE, 1);
        }

        // top panel
        topPanel = new JPanel(new BorderLayout(1, 0));
        topPanel.add(BorderLayout.WEST, Box.createRigidArea(new Dimension(timeLineWidth+1, 0)));
        topPanel.add(BorderLayout.CENTER, columnsPanel);

        // this
        this.setLayout(new BorderLayout(0, 0));
        this.add(BorderLayout.NORTH, topPanel);
        this.add(BorderLayout.CENTER, scrollPanel);
    }

    @Override
    public void next() {
        this.model.add(this.model.getDayNumbers());
        refresh();
    }

    @Override
    public void previous() {
        this.model.add(-this.model.getDayNumbers());
        refresh();
    }

    @Override
    public void refresh() {
        this.model.reloadEntries();
        this.removeAll();
        initComponents();
        this.revalidate();
    }

    @Override
    public void today() {
        Calendar today = Calendar.getInstance();
        today.set(Calendar.DATE, 1);
        long timeInMillis = (today.getTimeInMillis() - this.model.getFirstDay().getTimeInMillis());
        Timestamp timeSpan = new Timestamp(timeInMillis);
        System.out.println("days = " + timeSpan.toString());
    }

    @Override
    public String getCaption() {
        Calendar firstDay = model.getFirstDay();
        Calendar lastDay = model.getLastDay();
        String caption = firstDay.getDisplayName(Calendar.MONTH, Calendar.LONG, PreferenceController.getLocale());
        caption += " " + firstDay.get(Calendar.DATE);
        if (firstDay.get(Calendar.YEAR) != lastDay.get(Calendar.YEAR)) {
            caption += ", " + firstDay.get(Calendar.YEAR);
        }
        caption += " - ";
        if (firstDay.get(Calendar.MONTH) != lastDay.get(Calendar.MONTH)) {
            caption += lastDay.getDisplayName(Calendar.MONTH, Calendar.LONG, PreferenceController.getLocale()) + " ";
        }
        caption += lastDay.get(Calendar.DATE);
        caption += ", " + lastDay.get(Calendar.YEAR);
        return caption;
    }

    @Override
    public void jumpToDate(Calendar cal) {
    }

    public void notifyEntryChanged() {
        viewPanel.refreshLeftPanel();
    }

    @Override
    public void highlightEntriesByCategory(String category) {
    }

    @Override
    public void showEntriesByCategories(java.util.List<String> categories) {
    }

    @Override
    public void showEntriesByPriorities(ArrayList<String> priorities) {
    }

    public void jumpToMinicalDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        jumpToDate(cal);
    }
}
